package com.xjcs.saplingplan.socket

import android.os.Handler
import android.os.Looper
import android.util.Log
import org.java_websocket.client.WebSocketClient
import org.java_websocket.handshake.ServerHandshake
import java.net.URI
import java.net.URISyntaxException

class WebSocketManager private constructor() {
    companion object {
        @Volatile
        private var instance: WebSocketManager? = null

        fun getInstance(): WebSocketManager =
            instance ?: synchronized(this) {
                instance ?: WebSocketManager().also { instance = it }
            }
    }

    private var webSocketClient: WebSocketClient? = null
    var isConnected = false
    private var reconnectAttempts = 0
    private val maxReconnectAttempts = 0    //不重连了
    private var reconnectDelayMillis = 3000L // 3秒

    // ==================== 心跳相关字段 ====================
    private val HEARTBEAT_INTERVAL = 20000L // 20秒
    private var heartbeatRunnable: Runnable? = null
    private var isHeartbeatRunning = false

    private var connectionListener: ConnectionListener? = null

    //新增标志位，用于标识是否是手动断开连接
    private var isManualDisconnect = false

    fun init(serverUri: String, connectionListener: ConnectionListener) {
        //重置 isManualDisconnect = false，因为这是一个新的连接周期
        isManualDisconnect = false
        this.connectionListener = connectionListener
        try {
            val uri = URI(serverUri)
            webSocketClient = object : WebSocketClient(uri) {
                override fun onOpen(handshakedata: ServerHandshake?) {
                    isConnected = true
                    reconnectAttempts = 0
                    connectionListener.onConnected()
                    startHeartbeat() // 连接成功后启动心跳
                }

                override fun onMessage(message: String?) {
                    Log.i("based_onMessage", "$message")
                    message?.let {
                        if (isHeartbeatMessage(it)) {
                            // 收到心跳响应，不做处理
                            return
                        }
                        connectionListener.onMessageReceived(it)
                    }
                }

                override fun onClose(code: Int, reason: String?, remote: Boolean) {
                    Log.i("based_onClose", "$reason")
                    isConnected = false
                    stopHeartbeat() // 关闭连接时停止心跳
                    connectionListener.onDisconnected(code, reason)
                    if(!isManualDisconnect){
                        attemptReconnect()
                    }
                }

                override fun onError(ex: Exception?) {
                    Log.i("based_onClose", "${ex?.message}")
                    isConnected = false
                    stopHeartbeat() // 发生错误时停止心跳
                    connectionListener.onError(ex)
                    if (!isManualDisconnect && ex != null) {
                        attemptReconnect()
                    }
                }
            }.apply {
                connect()
            }
        } catch (e: URISyntaxException) {
            connectionListener.onError(e)
        }
    }

    fun sendMessage(message: String): Boolean {
        if (!isConnected || webSocketClient?.isOpen != true) {
            connectionListener?.onError(IllegalStateException("WebSocket not connected"))
            return false
        }

        return try {
            webSocketClient?.send(message)
            true
        } catch (e: Exception) {
            connectionListener?.onError(e)
            false
        }
    }

    fun disconnect() {
        isManualDisconnect = true //标记为手动断开
        stopHeartbeat()
        webSocketClient?.close()
        isConnected = false
    }

    private fun startHeartbeat() {
        if (isHeartbeatRunning) return

        isHeartbeatRunning = true
        heartbeatRunnable = object : Runnable {
            override fun run() {
                if (isConnected && webSocketClient?.isOpen == true) {
                    try {
                        val heartbeatMsg = "{\"action\":\"heartbeat\"}"
                        Log.i("based", heartbeatMsg)
                        webSocketClient?.send(heartbeatMsg)
                    } catch (e: Exception) {
                        connectionListener?.onError(e)
                        stopHeartbeat()
                    }
                }
                Handler(Looper.getMainLooper()).postDelayed(this, HEARTBEAT_INTERVAL)
            }
        }
        Handler(Looper.getMainLooper()).post(heartbeatRunnable!!)
    }

    private fun stopHeartbeat() {
        isHeartbeatRunning = false
        heartbeatRunnable?.let {
            Handler(Looper.getMainLooper()).removeCallbacks(it)
            heartbeatRunnable = null
        }
    }

    private fun isHeartbeatMessage(message: String): Boolean {
        return message.contains("\"type\":\"heartbeat_response\"")
    }

    private fun attemptReconnect() {
        if (reconnectAttempts < maxReconnectAttempts) {
            reconnectAttempts++
            connectionListener?.onReconnecting(reconnectAttempts)
            Handler(Looper.getMainLooper()).postDelayed({
                webSocketClient?.reconnectBlocking()
            }, reconnectDelayMillis)
        } else {
            connectionListener?.onMaxReconnectAttemptsReached()
        }
    }

    interface ConnectionListener {
        fun onConnected()
        fun onDisconnected(code: Int, reason: String?)
        fun onMessageReceived(message: String)
        fun onError(error: Exception?)
        fun onReconnecting(attempt: Int)
        fun onMaxReconnectAttemptsReached()
    }
}